import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ComponentEvent;
import java.awt.event.ComponentListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.WindowEvent;
import java.awt.event.WindowListener;
import java.util.*;
import java.util.List;
import java.util.logging.Level;
import javax.accessibility.*;
import javax.swing.*;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;

import org.rsbot.bot.Bot;
import org.rsbot.script.*;
import org.rsbot.script.wrappers.*;
import org.rsbot.script.wrappers.RSItem;
import org.rsbot.script.wrappers.RSObject;
import org.rsbot.script.wrappers.RSPlayer;
import org.rsbot.accessors.*;
import org.rsbot.script.wrappers.RSNPC;
import org.rsbot.event.listeners.PaintListener;
import org.rsbot.event.listeners.ServerMessageListener;
import org.rsbot.event.events.ServerMessageEvent;
import org.rsbot.util.ScreenshotUtil;

@ScriptManifest(authors = { "Dietao234" }, category = "Combat", name = "DietaoSoldier", version = 1.0, description = "<html><head></head><body>DietaoSoldier RC1</body></html\n")
public class DietaoSoldier extends Script implements PaintListener, ServerMessageListener {
	final int[] STR = { 113, 115, 117, 119, 2440, 157, 159, 161, 9739, 9741,9743, 9745 };
	final int[] DEF = { 2442, 163, 165, 167, 137, 135, 133, 2432 };
	final int[] ATT = { 2436, 145, 147, 149, 2428, 121, 123, 125, 9739, 9741,9743, 9745 };
	boolean proccessed = false;
	boolean maybegin = false;
	int killscount = 0;
	long starttime = System.currentTimeMillis();
	int startbreaktimes[] = {4500000 + (int)(Math.random()*1800000-900000), 7200000 + (int)(Math.random()*600000-300000), 12600000 + (int)(Math.random()*1800000-900000), 17400000 + (int)(Math.random()*1200000-600000)};
	int breakfor[] = {1200000 + (int)(Math.random()*600000-300000), 1800000 + (int)(Math.random()*600000-300000), 600000 + (int)(Math.random()*600000-300000), 600000 + (int)(Math.random()*600000-300000)};
	//Settings frame
	JFrame frame;

	JTabbedPane settings = new JTabbedPane();

	//first tab fields
	JPanel monsters;
	JTextField monsterid;
	JPanel submit;
	JCheckBox eat;
	JTextField eatid;

	//second tab fields
	JCheckBox arrow;
	JTextField arrowid;
	JTextField wieldat;
	JPanel arrows;

	//third tab fields
	JCheckBox pickup;
	JTextField pickupid;
	JTextField pickupitemsname;
	JPanel pickuppanel;

	//bones tab fields
	JPanel pbpanel;
	JCheckBox pb;
	JCheckBox lessbones;

	public boolean onStart(Map<String, String> args) {
		int breakin = (int)(startbreaktimes[0]-(System.currentTimeMillis()-starttime));
		int seconds = ((int)(breakin/1000))%60;
		int minutes = (((int)(breakin/1000))-seconds)/60;
		int minutest = minutes;
		minutes = minutes%60;
		int hours = (minutest-minutes)/60;
		log("First break in " + hours + ":" + minutes + ":" + seconds);
		frame = new JFrame("DietaoSoldier by Dietao234");
		frame.setSize(650,215);
		frame.setVisible(true);
		frame.setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE);
		frame.setLayout(new FlowLayout());

		monsters = new JPanel();
		monsters.setLayout(new BoxLayout(monsters, BoxLayout.Y_AXIS));
		monsters.add(new JLabel("Put the monster IDs you would like to fight in the following text box seperated with a space (eg. 123, 132, 321):"));
		eat = new JCheckBox("Eat food?");
		eat.addItemListener(new Changed());
		eatid = new JTextField(10);
		eatid.setEnabled(false);
		monsterid = new JTextField(10);
		monsterid.setText(null);
		monsters.add(monsterid);
		monsters.add(eat);
		monsters.add(new JLabel("Please enter the ID of the food that you wish to eat: Food will be eaten when your hp falls below 50%"));
		monsters.add(eatid);
		settings.addTab("Monster + Food/Eating", monsters);

		arrows = new JPanel();
		arrow = new JCheckBox("Wield arrows? (Make sure that you select to pick up arrows in the next tab!)");
		arrow.addItemListener(new Changed());
		arrowid = new JTextField();
		arrowid.setEnabled(false);
		arrowid.setText(null);
		wieldat = new JTextField();
		wieldat.setEnabled(false);
		wieldat.setText(null);
		arrows.setLayout(new BoxLayout(arrows, BoxLayout.Y_AXIS));
		arrows.add(arrow);
		arrows.add(new JLabel("Enter the id of the arrows you wish to wield:"));
		arrows.add(arrowid);
		arrows.add(new JLabel("How many arrows do you wish to pick up before wielding? (The actual amount will be +/- 10 arrows of your set number)."));
		arrows.add(wieldat);
		settings.addTab("Arrows", arrows);

		pickuppanel = new JPanel();
		pickuppanel.setLayout(new BoxLayout(pickuppanel, BoxLayout.Y_AXIS));
		pickup = new JCheckBox("Pick up items?");
		pickup.addItemListener(new Changed());
		pickupid = new JTextField();
		pickupid.setEnabled(false);
		pickupid.setText(null);
		pickupitemsname = new JTextField();
		pickupitemsname.setEnabled(false);
		pickupitemsname.setText(null);
		pickuppanel.add(pickup);
		pickuppanel.add(new JLabel("Put here the IDs of what you want to pick up"));
		pickuppanel.add(pickupid);
		pickuppanel.add(new JLabel("Put the name of the items you want to pick up"));
		pickuppanel.add(pickupitemsname);
		settings.addTab("Pickup Items", pickuppanel);

		pb = new JCheckBox("Pickup and bury bones?");
		pbpanel = new JPanel();
		pbpanel.setLayout(new BoxLayout(pbpanel, BoxLayout.Y_AXIS));
		pbpanel.add(pb);
		pbpanel.add(new JLabel("Luckily, because of the way my code works, bones will be picked up randomly, but will be buried right after it is picked up."));
		lessbones = new JCheckBox("Click this to pick up less bones (Will get more xp)");
		pbpanel.add(lessbones);
		settings.addTab("Bones", pbpanel);

		submit = new JPanel();
		JButton start = new JButton("Start!");
		submit.add(start);
		start.addActionListener(new Start());

		frame.add(new JLabel("Welcome to DietaoSoldier by Dietao234"));
		frame.add(settings);
		frame.add(start);
		processLoop();
		return true;
	}

	private class Start implements ActionListener {
		public void actionPerformed(ActionEvent arg0) {
			maybegin = true;
			frame.dispose();
		}

	}
	private class Changed implements ItemListener {

		public void itemStateChanged(ItemEvent arg0) {
			if(eat.isSelected()){
				eatid.setEnabled(true);
			}
			else{
				eatid.setEnabled(false);
			}
			if(arrow.isSelected()){
				arrowid.setEnabled(true);
				wieldat.setEnabled(true);
			}
			else{
				arrowid.setEnabled(false);
				wieldat.setEnabled(false);
			}
			if(pickup.isSelected()){
				pickupid.setEnabled(true);
				pickupitemsname.setEnabled(true);
			}
			else{
				pickupid.setEnabled(false);
				pickupitemsname.setEnabled(false);
			}
		}

	}
	RSNPC killmonster;
	String pickuptext;
	String monstertext;
	int monsters1[];
	int eatids = 0;
	int arrowids = 0;
	int pickupids[];
	String[] names;
	int wieldatc = 0;
	public void processLoop(){
		if(maybegin){
			proccessed = true;
			pickuptext = "";
			for(int i = 0; i < pickuptext.length(); i++){
				if(pickuptext.charAt(i)==','){
					pickuptext = pickuptext.substring(0, i) + " " + pickuptext.substring(i+1,pickuptext.length());
				}
			}
			if(eat.isSelected()){
				eatids = Integer.parseInt(eatid.getText());
			}
			if(arrow.isSelected()){
				arrowids = Integer.parseInt(arrowid.getText());
				wieldatc = Integer.parseInt(wieldat.getText());
			}
			if(pickup.isSelected()){
				pickuptext = pickupid.getText();
			}
			monstertext = monsterid.getText();
			for(int i = 0; i < monstertext.length(); i++){
				if(monstertext.charAt(i)==','){
					monstertext = monstertext.substring(0, i) + " " + monstertext.substring(i+1,monstertext.length());
				}
			}
			Scanner read = new Scanner(monstertext);
			int monsterc = 0;
			while(read.hasNext()){
				monsterc++;
				read.nextInt();
			}
			read = new Scanner(monstertext);
			monsters1 = new int[monsterc];
			for(int i = 0; i < monsters1.length; i++){
				monsters1[i] = read.nextInt();
			}
			pickuptext = pickuptext.replace(',' , ' ');
			read = new Scanner(pickuptext);
			int pickupc = 0;
			while(read.hasNext()){
				pickupc++;
				read.next();
			}
			read = new Scanner(pickuptext);
			pickupids = new int[pickupc];
			for(int i = 0; i < pickupids.length; i++){
				pickupids[i] = read.nextInt();
			}
			pickupitemsname.setText(pickupitemsname.getText().replace(',', ' '));
			read = new Scanner(pickupitemsname.getText());
			names = new String[pickupc];
			for(int i = 0; i < names.length; i++){
				names[i] = read.next();
			}
			if(maybegin){
				attack(monsters1);
			}
		}
	}
	public int loop() {
		if(maybegin){
			if(proccessed == false){
				processLoop();
			}
			if(isLoggedIn()){
				if (runCheck()) {
					setRun(true);
					wait(random(450, 950));
				}
				if(getMyPlayer().getAnimation() == -1){
					wait(random(500,700));
					if(getMyPlayer().getAnimation() == -1){
						wait(random(500,700));
						if(getMyPlayer().getAnimation() == -1){
							wait(random(500,700));
							if(getMyPlayer().getAnimation() == -1){
								if(pickup.isSelected()){
									for(int i = 0; i < pickupids.length; i++){
										RSItemTile item = getNearestGroundItemByID(pickupids[i]);
										do{
										if(item!=null && !isInventoryFull())
											atTile(item, "Take " + names[i]);
										wait(random(500,800));
										while(getMyPlayer().isMoving()){
											
										}
										wait(random(500,700));
										item = getNearestGroundItemByID(pickupids[i]);
										}while(item!=null&&tileOnScreen(new RSTile(item.getX(), item.getY())));
									}
								}
								if(eat.isSelected()){
									while(getMyPlayer().getHPPercent()<(int)(Math.random()*10+40)){
										atInventoryItem(eatids, "Eat");
										//give time for the percent to be refreshed after eating
										wait(500);
									}
								}
								else{
									if(getMyPlayer().getHPPercent() < 10){
										stopScript();
									}
								}
								if(arrow.isSelected()){
									int arrowcount = getInventoryCount(arrowids);
									if(arrowcount > wieldatc - 10 + random(1,20)){
										atInventoryItem(arrowids, "Wield");
									}
								}
								if(killmonster != null && killmonster.getHPPercent()==0){
									killscount++;
								}
								if(pb.isSelected()){
									if(lessbones.isSelected()){
										if(!tileOnScreen(getNearestNPCByID(monsters1).getLocation())){
											if(!isInventoryFull()){
												RSItemTile bones = getNearestGroundItemByID(526);
												if(bones!=null){
													atTile(bones, "Take Bones");
													wait(random(500,700));
												}
												while(getMyPlayer().isMoving()){

												}
												wait(random(500,700));
											}
											if(isInventoryFull()){
												while(getInventoryCount(526)>0){
													atInventoryItem(526, "Bury");
													clickMouse(true);
													wait(random(1000,1200));
												}
											}
										}
									}else{
										if(!isInventoryFull()){
											RSItemTile bones = getNearestGroundItemByID(526);
											if(bones!=null){
												atTile(bones, "Take Bones");
												wait(random(500,700));
											}
											while(getMyPlayer().isMoving()){

											}
											wait(random(500,700));
										}
										if(isInventoryFull()){
											while(getInventoryCount(526)>0){
												atInventoryItem(526, "Bury");
												clickMouse(true);
												wait(random(1000,1200));
											}
										}
									}
								}
								if(getMyPlayer().getAnimation()==-1){
									attack(monsters1);
								}
							}
						}
					}
				}
			}
		}
		return 100;
	}

	private void attack(int[] monsters) {
		killmonster = getNearestFreeNPCByID(monsters);
		if(killmonster != null){
			if(!tileOnScreen(killmonster.getLocation())){
				if(!getMyPlayer().isMoving())
					walkTileMM(killmonster.getLocation());
				wait(random(500,700));
				while(getMyPlayer().isMoving()){

				}
				attack(monsters);
			}
			else{
				if(!getMyPlayer().isMoving()){
					atNPC(killmonster,"Attack");
					wait(500);
				}
			}
		}
	}
	public void checkBreak(){
		int breakindex;
		for(breakindex = 0; breakindex < startbreaktimes.length; breakindex++){
			if(System.currentTimeMillis()-starttime < startbreaktimes[breakindex]){
				break;
			}
		}
		if(breakindex==startbreaktimes.length){
			wait(20000);
			logout();
			stopScript();
		}
		else if(breakindex != 0 && (System.currentTimeMillis()-starttime)-startbreaktimes[breakindex-1] < 60000){
			if(isLoggedIn()){
				wait(20000);
				int seconds = ((int)(breakfor[breakindex-1]/1000))%60;
				int minutes = (((int)(breakfor[breakindex-1]/1000))-seconds)/60;
				int minutest = minutes;
				minutes = minutes%60;
				int hours = (minutest-minutes)/60;
				log("Taking break for " + hours + ":" + minutes + ":" + seconds);
				logout();
				wait(breakfor[breakindex-1]);
				int breakin = (int)(startbreaktimes[breakindex]-(System.currentTimeMillis()-starttime));
				seconds = ((int)(breakin/1000))%60;
				minutes = (((int)(breakin/1000))-seconds)/60;
				minutest = minutes;
				minutes = minutes%60;
				hours = (minutest-minutes)/60;
				log("Next break in " + hours + ":" + minutes + ":" + seconds);
			}
		}
	}
	public void serverMessageRecieved(final ServerMessageEvent arg0) {
		final String serverString = arg0.getMessage();
	}

	public void onRepaint(Graphics g) {
		if(isLoggedIn() ||  isLoginScreen()) {
			g.drawString("You have killed " + killscount + " monsters",7,149);
			g.setColor(Color.GREEN);
			g.drawString("You are " + skills.getPercentToNextLevel(Skills.getStatIndex("attack")) + "% to the next ATTACK level with " + skills.getXPToNextLevel(Skills.getStatIndex("attack")) + " xp left.", 8, 32);
			g.drawString("You are " + skills.getPercentToNextLevel(Skills.getStatIndex("strength")) + "% to the next STRENGTH level with " + skills.getXPToNextLevel(Skills.getStatIndex("strength")) + " xp left.", 8, 44);
			g.drawString("You are " + skills.getPercentToNextLevel(Skills.getStatIndex("defence")) + "% to the next DEFENCE level with " + skills.getXPToNextLevel(Skills.getStatIndex("defence")) + " xp left.", 8, 56);
			g.drawString("You are " + skills.getPercentToNextLevel(Skills.getStatIndex("hitpoints")) + "% to the next HITPOINTS level with " + skills.getXPToNextLevel(Skills.getStatIndex("hitpoints")) + " xp left.", 8, 68);
			g.drawString("You are " + skills.getPercentToNextLevel(Skills.getStatIndex("magic")) + "% to the next MAGIC level with " + skills.getXPToNextLevel(Skills.getStatIndex("magic")) + " xp left.", 8, 80);
			g.drawString("You are " + skills.getPercentToNextLevel(Skills.getStatIndex("range")) + "% to the next RANGE level with " + skills.getXPToNextLevel(Skills.getStatIndex("range")) + " xp left.", 8, 92);

		}
		/* TODO    Paint here */
	}

	public void onFinish() {
		ScreenshotUtil.takeScreenshot(true);
	}
	public int walkToX = 0000;
	public int walkToY = 0000;

	int runEnergy = random(15, 50);

	@Override
	public RSTile[] fixPath(final RSTile[] path) {
		final ArrayList<RSTile> newPath = new ArrayList<RSTile>();
		for (int i = 0; i < path.length - 1; i++) {
			final List<RSTile> temp1 = fixPath2(path[i], path[i + 1]);
			for (final RSTile element : temp1) {
				newPath.add(element);
			}
		}
		return newPath.toArray(new RSTile[newPath.size()]);
	}
	public boolean runCheck() { // Credits To Ruski
		try {
			if (getEnergy() >= runEnergy && !isRunning()) {
				runEnergy = random(15, 50);
				return true;
			} 
			else {
				return false;
			}
		} 
		catch (final Exception e) {
			log.log(Level.SEVERE, "runCheck() error: ", e);
			return false;
		}
	}

	public boolean walkContinuous(final RSTile[] path) {
		try {
			if (runCheck()) {
				setRun(true);
				wait(random(450, 950));
			}
			RSTile loc = new RSTile(0, 0);
			if (!getMyPlayer().isMoving()
					|| distanceTo(getDestination()) < random(5, 7)) {
				for (int a = path.length - 1; a >= 0; a--) {
					if (tileOnMap(path[a])) {
						loc = randomizeTile(path[a], 0, 0);
						if (tileOnMap(loc)) {
							walkTileMM(loc);
							wait(random(80, 180));
						}
						return true;
					}
				}
				return false;
			}
		} 
		catch (final Exception e) {
		}
		return true;
	}
	public boolean tileOnScreen(final RSTile t) { 
		final Point p = Calculations.tileToScreen(t, 0); 	
		int x = (int) p.getX();
		int y = (int) p.getY();
		return x > 38 && y > 38 && x < 478 && y < 307; 
	} 
	public boolean walkThere(final RSTile tile) {
		try {
			walkContinuous(fixPath(generateProperPath(tile)));
		} 
		catch (final Exception e) {
			log("What Happened?!");
		}
		if (distanceTo(tile) <= 3) {
			return true;
		}
		return false;
	}

}